package com.xadrez.modelo;

import java.util.ArrayList;
import java.util.List;

public class Bispo extends Peca {

    public Bispo() {
    }

    public Bispo(Jogador jogador, Tabuleiro tabuleiro) {
        super(jogador, tabuleiro);
    }

    @Override
    public List<Posicao> recuperaMovimentosPossiveis() {
        List<Posicao> lista = new ArrayList<Posicao>();
        lista.addAll(recuperaPosicoesANordeste());
        lista.addAll(recuperaPosicoesANoroeste());
        lista.addAll(recuperaPosicoesASudeste());
        lista.addAll(recuperaPosicoesASudoeste());

        return lista;
    }

    @Override
    public List<Posicao> recuperaMovimentosParaCheck() {
        List<Posicao> lista = new ArrayList<Posicao>();
        Posicao posicaoDoReiAdversario = getTabuleiro().getJogadorAdversario(getJogador()).getReiDoJogador().getPosicaoNoTabuleiro();

        if (getPosicaoNoTabuleiro().getX() > posicaoDoReiAdversario.getX()
                && getPosicaoNoTabuleiro().getY() > posicaoDoReiAdversario.getY()) {
            lista = recuperaPosicoesAmeacadorasANoroeste();
        } else if (getPosicaoNoTabuleiro().getX() < posicaoDoReiAdversario.getX()
                && getPosicaoNoTabuleiro().getY() > posicaoDoReiAdversario.getY()) {
            lista = recuperaPosicoesAmeacadorasASudoeste();
        } else if (getPosicaoNoTabuleiro().getX() < posicaoDoReiAdversario.getX()
                && getPosicaoNoTabuleiro().getY() < posicaoDoReiAdversario.getY()) {
            lista = recuperaPosicoesAmeacadorasASudeste();
        } else if (getPosicaoNoTabuleiro().getX() > posicaoDoReiAdversario.getX()
                && getPosicaoNoTabuleiro().getY() < posicaoDoReiAdversario.getY()) {
            lista = recuperaPosicoesAmeacadorasANordeste();
        }

        if (lista != null && !lista.isEmpty()) {
            lista.add(getPosicaoNoTabuleiro());
        }

        return lista;
    }

    // <editor-fold defaultstate="collapsed" desc="MÉTODOS DE RECUPERAÇÃO">
    private List<Posicao> recuperaPosicoesANordeste() {
        List<Posicao> lista = new ArrayList<Posicao>();
        boolean continua = true;

        int x = this.getPosicaoNoTabuleiro().getX() + 1;
        int y = this.getPosicaoNoTabuleiro().getY() + 1;

        while (continua && x < 8 && y < 8) {
            if (getTabuleiro().temPecaDoJogadorNaPosicao(x, y, getJogador())) {
                continua = false;
            } else if (getTabuleiro().temAdversarioNaPosicao(x, y)) {
                if (!deixaReiEmCheck(new Posicao(x, y))) {
                    lista.add(new Posicao(x, y));
                }
                continua = false;
            } else {
                if (!deixaReiEmCheck(new Posicao(x, y))) {
                    lista.add(new Posicao(x, y));
                }
            }
            x++;
            y++;
        }

        return lista;
    }

    private List<Posicao> recuperaPosicoesANoroeste() {
        List<Posicao> lista = new ArrayList<Posicao>();
        boolean continua = true;

        int x = this.getPosicaoNoTabuleiro().getX() - 1;
        int y = this.getPosicaoNoTabuleiro().getY() + 1;

        while (continua && y < 8 && x >= 0) {
            if (getTabuleiro().temPecaDoJogadorNaPosicao(x, y, getJogador())) {
                continua = false;
            } else if (getTabuleiro().temAdversarioNaPosicao(x, y)) {
                if (!deixaReiEmCheck(new Posicao(x, y))) {
                    lista.add(new Posicao(x, y));
                }
                continua = false;
            } else {
                if (!deixaReiEmCheck(new Posicao(x, y))) {
                    lista.add(new Posicao(x, y));
                }
            }
            x--;
            y++;
        }

        return lista;
    }

    private List<Posicao> recuperaPosicoesASudoeste() {
        List<Posicao> lista = new ArrayList<Posicao>();
        boolean continua = true;

        int x = this.getPosicaoNoTabuleiro().getX() - 1;
        int y = this.getPosicaoNoTabuleiro().getY() - 1;

        while (continua && y >= 0 && x >= 0) {
            if (getTabuleiro().temPecaDoJogadorNaPosicao(x, y, getJogador())) {
                continua = false;
            } else if (getTabuleiro().temAdversarioNaPosicao(x, y)) {
                if (!deixaReiEmCheck(new Posicao(x, y))) {
                    lista.add(new Posicao(x, y));
                }
                continua = false;
            } else {
                if (!deixaReiEmCheck(new Posicao(x, y))) {
                    lista.add(new Posicao(x, y));
                }
            }
            x--;
            y--;
        }

        return lista;
    }

    private List<Posicao> recuperaPosicoesASudeste() {
        List<Posicao> lista = new ArrayList<Posicao>();
        boolean continua = true;

        int x = this.getPosicaoNoTabuleiro().getX() + 1;
        int y = this.getPosicaoNoTabuleiro().getY() - 1;

        while (continua && y >= 0 && x < 8) {
            if (getTabuleiro().temPecaDoJogadorNaPosicao(x, y, getJogador())) {
                continua = false;
            } else if (getTabuleiro().temAdversarioNaPosicao(x, y)) {
                if (!deixaReiEmCheck(new Posicao(x, y))) {
                    lista.add(new Posicao(x, y));
                }
                continua = false;
            } else {
                if (!deixaReiEmCheck(new Posicao(x, y))) {
                    lista.add(new Posicao(x, y));
                }
            }
            x++;
            y--;
        }

        return lista;
    }

    private List<Posicao> recuperaPosicoesAmeacadorasASudeste() {
        List<Posicao> lista = new ArrayList<Posicao>();
        boolean continua = true;

        int x = this.getPosicaoNoTabuleiro().getX() + 1;
        int y = this.getPosicaoNoTabuleiro().getY() + 1;

        while (continua && x < 8 && y < 8) {
            if (getTabuleiro().temPecaDoJogadorNaPosicao(x, y, getJogador())) {
                continua = false;
            } else if (getTabuleiro().temAdversarioNaPosicao(x, y)) {
                lista.add(new Posicao(x, y));
                continua = false;
            } else {
                lista.add(new Posicao(x, y));
            }
            x++;
            y++;
        }

        return lista;
    }

    private List<Posicao> recuperaPosicoesAmeacadorasANordeste() {
        List<Posicao> lista = new ArrayList<Posicao>();
        boolean continua = true;

        int x = this.getPosicaoNoTabuleiro().getX() - 1;
        int y = this.getPosicaoNoTabuleiro().getY() + 1;

        while (continua && y < 8 && x >= 0) {
            if (getTabuleiro().temPecaDoJogadorNaPosicao(x, y, getJogador())) {
                continua = false;
            } else if (getTabuleiro().temAdversarioNaPosicao(x, y)) {
                lista.add(new Posicao(x, y));
                continua = false;
            } else {
                lista.add(new Posicao(x, y));
            }
            x--;
            y++;
        }

        return lista;
    }

    private List<Posicao> recuperaPosicoesAmeacadorasANoroeste() {
        List<Posicao> lista = new ArrayList<Posicao>();
        boolean continua = true;

        int x = this.getPosicaoNoTabuleiro().getX() - 1;
        int y = this.getPosicaoNoTabuleiro().getY() - 1;

        while (continua && y >= 0 && x >= 0) {
            if (getTabuleiro().temPecaDoJogadorNaPosicao(x, y, getJogador())) {
                continua = false;
            } else if (getTabuleiro().temAdversarioNaPosicao(x, y)) {
                lista.add(new Posicao(x, y));
                continua = false;
            } else {
                lista.add(new Posicao(x, y));
            }
            x--;
            y--;
        }

        return lista;
    }

    private List<Posicao> recuperaPosicoesAmeacadorasASudoeste() {
        List<Posicao> lista = new ArrayList<Posicao>();
        boolean continua = true;

        int x = this.getPosicaoNoTabuleiro().getX() + 1;
        int y = this.getPosicaoNoTabuleiro().getY() - 1;

        while (continua && y >= 0 && x < 8) {
            if (getTabuleiro().temPecaDoJogadorNaPosicao(x, y, getJogador())) {
                continua = false;
            } else if (getTabuleiro().temAdversarioNaPosicao(x, y)) {
                lista.add(new Posicao(x, y));
                continua = false;
            } else {
                lista.add(new Posicao(x, y));
            }
            x++;
            y--;
        }

        return lista;
    }

    private List<Posicao> recuperaPosicoesAteOReiASudeste() {
        List<Posicao> lista = new ArrayList<Posicao>();
        boolean achouRei = false;

        int x = this.getPosicaoNoTabuleiro().getX() + 1;
        int y = this.getPosicaoNoTabuleiro().getY() + 1;

        while (x < 8 && y < 8) {
            lista.add(new Posicao(x, y));
            achouRei = getTabuleiro().temReiAdversarioNaPosicao(x, y, getJogador());
            x++;
            y++;
        }

        if (!achouRei) {
            lista = new ArrayList<Posicao>();
        }

        return lista;
    }

    private List<Posicao> recuperaPosicoesAteOReiANordeste() {
        List<Posicao> lista = new ArrayList<Posicao>();
        boolean achouRei = false;

        int x = this.getPosicaoNoTabuleiro().getX() - 1;
        int y = this.getPosicaoNoTabuleiro().getY() + 1;

        while (y < 8 && x >= 0) {
            lista.add(new Posicao(x, y));
            achouRei = getTabuleiro().temReiAdversarioNaPosicao(x, y, getJogador());
            x--;
            y++;
        }

        if (!achouRei) {
            lista = new ArrayList<Posicao>();
        }

        return lista;
    }

    private List<Posicao> recuperaPosicoesAteOReiANoroeste() {
        List<Posicao> lista = new ArrayList<Posicao>();
        boolean achouRei = false;

        int x = this.getPosicaoNoTabuleiro().getX() - 1;
        int y = this.getPosicaoNoTabuleiro().getY() - 1;

        while (y >= 0 && x >= 0) {
            lista.add(new Posicao(x, y));
            achouRei = getTabuleiro().temReiAdversarioNaPosicao(x, y, getJogador());
            x--;
            y--;
        }

        if (!achouRei) {
            lista = new ArrayList<Posicao>();
        }

        return lista;
    }

    private List<Posicao> recuperaPosicoesAteOReiASudoeste() {
        List<Posicao> lista = new ArrayList<Posicao>();
        boolean achouRei = false;

        int x = this.getPosicaoNoTabuleiro().getX() + 1;
        int y = this.getPosicaoNoTabuleiro().getY() - 1;

        while (y >= 0 && x < 8) {
            lista.add(new Posicao(x, y));
            achouRei = getTabuleiro().temReiAdversarioNaPosicao(x, y, getJogador());
            x++;
            y--;
        }

        if (!achouRei) {
            lista = new ArrayList<Posicao>();
        }
        return lista;
    }
    // </editor-fold>

    @Override
    public String toString() {
        return "bispo";
    }

    @Override
    public List<Posicao> caminhoAteOReiAdversario() {
        List<Posicao> lista = new ArrayList<Posicao>();
        Posicao posicaoDoReiAdversario = getTabuleiro().getJogadorAdversario(getJogador()).getReiDoJogador().getPosicaoNoTabuleiro();

        if (getPosicaoNoTabuleiro().getX() > posicaoDoReiAdversario.getX()
                && getPosicaoNoTabuleiro().getY() > posicaoDoReiAdversario.getY()) {
            lista = recuperaPosicoesAteOReiANoroeste();
        } else if (getPosicaoNoTabuleiro().getX() < posicaoDoReiAdversario.getX()
                && getPosicaoNoTabuleiro().getY() > posicaoDoReiAdversario.getY()) {
            lista = recuperaPosicoesAteOReiASudoeste();
        } else if (getPosicaoNoTabuleiro().getX() < posicaoDoReiAdversario.getX()
                && getPosicaoNoTabuleiro().getY() < posicaoDoReiAdversario.getY()) {
            lista = recuperaPosicoesAteOReiASudeste();
        } else if (getPosicaoNoTabuleiro().getX() > posicaoDoReiAdversario.getX()
                && getPosicaoNoTabuleiro().getY() < posicaoDoReiAdversario.getY()) {
            lista = recuperaPosicoesAteOReiANordeste();
        }

        if (lista != null && !lista.isEmpty()) {
            lista.add(getPosicaoNoTabuleiro());
        }

        return lista;
    }
}
